Getting started with arrays in Julia using images

(Following this Computational Thinking Course by MIT and JuliaImages and Tutorialspoint's Julia Tutorial)

Julia has been touted as the next best thing in computational programming, potentially replacing fan favourite, Python, as the go to language for data science and machine learning.

https://twitter.com/JuliaLanguage/status/1477307810564169731

I have been looking to learn Julia for some time, and have finally gathered the courage to begin, following the MIT's 2021 Computational Thinking course and Tutorialspoint tutorial. The hope is to use Julia for quantitative economics, agent-based models and related interests (and some data science and machine learning of course!).

Some introductory concepts like installation, environments, packages and variables I have skipped to dive into the language. The Tutorialspoint tutorial gives quite good explanations for these.

Arrays are key to computational work, providing the building blocks for programming work in data science and machine learning. In this piece, I will use images to explore arrays. An array in Julia is a set of items "specified with square brackets" that can contain similar items or different items.

  1. Creating arrays...
arr = [1,2,3]
3-element Vector{Int64}:
 1
 2
 3
arr1 = ["Leonard", tan, 26, 1.245]
4-element Vector{Any}:
   "Leonard"
   tan (generic function with 12 methods)
 26
  1.245
Array[1:10]
1-element Vector{Array}:
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
arr2 = Array{Int64}(undef, 2, 2) #Create a 2x2 array(matrix) with undefined values of type Integer64
2×2 Matrix{Int64}:
 0  0
 0  0
Array[1:5,5:9]
2-element Vector{Array}:
 [1, 2, 3, 4, 5]
 [5, 6, 7, 8, 9]
collect(1:2:20)
10-element Vector{Int64}:
  1
  3
  5
  7
  9
 11
 13
 15
 17
 19
arr3 = collect(range(1, 15, 30))
30-element Vector{Float64}:
  1.0
  1.4827586206896552
  1.9655172413793103
  2.4482758620689653
  2.9310344827586206
  3.413793103448276
  3.896551724137931
  4.379310344827586
  4.862068965517241
  5.344827586206897
  ⋮
 11.137931034482758
 11.620689655172415
 12.10344827586207
 12.586206896551724
 13.068965517241379
 13.551724137931034
 14.03448275862069
 14.517241379310345
 15.0

Collect uses (start:step:stop) format whilst range uses (start, stop, length).

[1:10...] #using the ellipses
10-element Vector{Int64}:
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10

A matrix can be created by specifying the arrays, separating the rows with a semi-colon (;)

matrix = [[1 2];[3 4]]
2×2 Matrix{Int64}:
 1  2
 3  4

Compare with..

arr4 = [[1 2], [3 4]]
2-element Vector{Matrix{Int64}}:
 [1 2]
 [3 4]
tensor = Array{Float32}(undef, 3, 3, 3)
3×3×3 Array{Float32, 3}:
[:, :, 1] =
 1.1f-44  0.0      2.7f-44
 0.0      2.1f-44  0.0
 2.0f-44  0.0      3.0f-44

[:, :, 2] =
 0.0      3.6f-44  0.0
 3.2f-44  0.0      3.9f-44
 0.0      3.8f-44  0.0

[:, :, 3] =
 4.2f-44  0.0      5.0f-44
 0.0      4.5f-44  0.0
 4.3f-44  0.0      5.3f-44
  1. Manipulating arrays..

These functions change the array in place, nota bene.

push!(arr, 10)
4-element Vector{Int64}:
  1
  2
  3
 10
pushfirst!(arr, 27)
5-element Vector{Int64}:
 27
  1
  2
  3
 10
splice!(arr, 3, 12)
2
pop!(arr)
10
arr
4-element Vector{Int64}:
 27
  1
 12
  3
  1. Arrays with images
using Images #importing a package (use add Package to install the package)
path_to_image = "..\\images\\Brain-Teaser2.png"
img = load(path_to_image)
Julia, in the notebook automatically shows the read image. Cool! Also Julia strings are double quotes ONLY, nota bene.
size(img)
(578, 1255)
img[100, 200]
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
RGB(0, 0, 1)
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
Another really cool feature from Julia. Can you do this in Python?
brain = img[100:470, 350:900]
save("..\\images\\brain.png", brain)
0

Kaleidoscope The last element of an array is "end" compared to -1 in python

[
    img img[:, end:-1:1]
    img[end:-1:1,:] img[end:-1:1, end:-1:1]
]
imgc = rand(RGB{Base.Float32}, 3, 3)
dump(imgc) #dump gives the internal representation of an object
Array{RGB{Float32}}((3, 3))
  1: RGB{Float32}
    r: Float32 0.14813906f0
    g: Float32 0.022337258f0
    b: Float32 0.290174f0
  2: RGB{Float32}
    r: Float32 0.29126495f0
    g: Float32 0.68497497f0
    b: Float32 0.32906735f0
  3: RGB{Float32}
    r: Float32 0.9255593f0
    g: Float32 0.38232696f0
    b: Float32 0.7527777f0
  4: RGB{Float32}
    r: Float32 0.99836004f0
    g: Float32 0.029634118f0
    b: Float32 0.93390673f0
  5: RGB{Float32}
    r: Float32 0.14359307f0
    g: Float32 0.9928523f0
    b: Float32 0.48511934f0
  6: RGB{Float32}
    r: Float32 0.4660908f0
    g: Float32 0.6281384f0
    b: Float32 0.7955537f0
  7: RGB{Float32}
    r: Float32 0.36805505f0
    g: Float32 0.53995806f0
    b: Float32 0.17738062f0
  8: RGB{Float32}
    r: Float32 0.25911433f0
    g: Float32 0.6903035f0
    b: Float32 0.15376025f0
  9: RGB{Float32}
    r: Float32 0.72552717f0
    g: Float32 0.36271602f0
    b: Float32 0.34703147f0
imgc[2,3]
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
dump(imgc[2,3])
RGB{Float32}
  r: Float32 0.25911433f0
  g: Float32 0.6903035f0
  b: Float32 0.15376025f0
c = imgc[2,3]; (red(c), green(c), blue(c))
(0.25911433f0, 0.6903035f0, 0.15376025f0)
[RGB(x, 1, 1) for x in 0:0.1:1.0]
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
[
    RGB(x, y, 1) for x in 0:0.1:1.0, y in 0:0.1:1.0
]

Other cool things in Julia to do with images. To be explored more in a later post. Mosaicview makes it easy to juxtapose images, or stack them. Rot180 and reverse are self explaining.

pex = load("../images/pexels-photo-2422290.jpeg")
size(pex)
(750, 1042)
mosaicview(img, pex)
mosaicview(img, pex; nrow=1)
rot180(img)
reverse(pex)
  1. Synthetic images using random numbers
img_gen = randn(300, 250, 3)
300×250×3 Array{Float64, 3}:
[:, :, 1] =
 -0.456114   -0.476913   -0.0604701  -2.91558    …  -0.101747    -1.18882
 -1.12386    -2.28454     0.470605    0.0231328     -0.571642    -1.69385
  0.0210224   0.134183   -2.35678    -1.12899       -0.609866     0.118872
  0.569517   -0.247305    0.228133   -1.88472       -1.06537      0.0919288
  0.0609009   3.12994     3.50737    -1.44209        0.919902    -0.738038
 -0.723276    0.43649    -0.245939    0.26377    …   0.411805     0.645772
  0.998808    2.18767     1.10362     0.231542       1.66792      1.55992
 -0.669666    0.467104    0.229961    0.928862      -0.890484    -0.155007
  2.62532    -0.919264   -0.475943   -0.355377      -1.0266      -0.853989
 -0.776415    1.22461     0.137224    0.0115602     -1.11155      0.44724
  ⋮                                              ⋱               
  0.0587484  -0.55652    -0.916055   -0.0766243     -0.709722    -2.14006
  1.54682    -1.75232    -0.311055   -0.206338       0.456843    -0.833676
  0.849251    0.231314   -0.503181   -0.399324      -0.558501     0.325638
  0.270414   -0.227391   -0.180145    0.295521      -0.00454061  -0.286905
 -0.433926   -0.13708    -1.03994     0.215816   …   0.239418    -0.197361
 -0.14266    -1.15523    -0.563557    1.62214        0.588717    -1.18474
 -0.166872    1.03946     0.41584     1.33767        0.031894     0.202908
  1.22879    -0.0536496  -1.40622     0.78945       -1.67875     -0.696194
  1.51641     1.64796     0.148725   -0.385578      -1.01254      2.38786

[:, :, 2] =
 -0.726833   1.89302    1.9287    …   1.96989     0.520231     1.88241
 -0.33641    2.44182    0.392613      1.84573    -0.510835    -0.167692
  1.08963   -0.832815   2.54401       1.08435    -0.420101    -0.419483
  0.788582  -0.107246  -1.19661      -0.546581   -1.09842     -0.761246
 -0.3369     0.451329   0.763138     -1.46531    -0.766336    -0.510274
  0.753169   0.889348  -1.02313   …   0.398426    1.27975     -0.341834
 -0.798053   0.873408   0.361995     -0.521996   -0.00470363  -0.415646
  1.37224    2.15666    2.04041      -0.918365    1.32887      0.15058
  1.03195   -0.143432  -1.68968      -1.59421     0.596801     1.52271
  0.521335   0.219754   0.88636       0.560813   -1.02787     -1.89114
  ⋮                               ⋱                           
  3.20634    0.743989  -0.546743      0.752237    0.252715    -0.443444
  1.02283   -0.814689   0.6918        0.823001    0.538502     0.0853114
  0.847397  -0.896043  -0.450898     -0.643641    1.76131      1.28218
  0.132522  -0.536538  -1.04116      -1.58416     0.459093     0.0123447
  0.501659  -1.09022    0.729411  …  -0.974185    1.06419      1.16817
 -0.165907  -0.287186  -0.426526     -0.0454588  -0.508658    -1.18004
  0.895043   1.61529    1.11219       1.2329     -1.39967     -0.0656508
 -1.27477   -1.42699    0.256276     -1.0209      0.418269    -1.68731
  0.452192   0.921081   0.626108      1.07219     1.85219      0.137243

[:, :, 3] =
 -0.524386   -0.0495246  -0.500409    …   1.59546     0.0257901   1.51875
 -1.44672     0.145577   -0.762651       -0.385093   -0.316218    1.44452
 -1.03128     1.26944     1.03845         0.460778    1.52936     0.104888
 -0.242745   -0.91783     1.2682         -0.524241    1.53924     0.873882
  2.38385     0.201837   -0.0425648       1.7537     -2.83745     0.183214
 -0.959068   -0.280875    1.00312     …  -0.0338207   1.03482     0.200956
  0.168486    0.127249    1.29314         0.143987    0.101661   -1.23765
  0.270497    0.776357   -1.73811        -1.04057    -1.23815    -0.652999
 -1.16591     0.657618   -0.591483       -0.93871    -0.285952   -1.77754
 -0.566652   -0.518922   -2.82427        -0.19411     0.366914   -2.24776
  ⋮                                   ⋱                          
 -0.483154    0.911862    0.363789        0.0221711  -0.809007    0.0464754
  2.28239    -0.531603    0.507493        0.283508    0.507982   -2.16083
  1.74327     0.298282    0.328872        0.0389795   2.94941    -0.375352
  1.45181    -0.434221   -0.219281        0.487231   -0.276103   -0.0348828
 -0.335905    0.408986   -0.025241    …   1.13776     1.89519    -0.72062
 -0.287219   -0.33048     0.00261884     -0.856536   -1.92094     0.255085
 -1.25252     1.05689    -1.51396        -0.45681    -1.60057     0.518345
  0.175404   -1.0295      0.304172       -0.786066   -0.231639    1.21375
 -0.0980951  -0.353327    0.687904        0.872077    1.13425    -0.184697
colorview(RGB, reshape(img_gen, 3, 300, 250))
colorview(RGB, reshape(img_gen, (3, 250, 300)))